home *** CD-ROM | disk | FTP | other *** search
- /*************************************************************************
- * ----------------
- * | CLEMDCMP |
- * ----------------
- *
- *_TITLE CLEMDCMP Decompress clementine image into various formats
- *
- *_DESC CLEMDCMP will decompress a clementine image and format it into
- * one of four possible formats:
- * 1) decompressed pds image file, with pds labels, the historgram
- * object, and an image object, either the browse image or
- * the full image
- * 2) decompressed image file, no labels
- * 3) decompressed gif image
- * 4) decompressed tiff image
- * This version is specifically for the Macintosh environment
- *
- *_HIST Apr 07 1994 Tracie Sucharski, USGS, Flagstaff Original Version
- * Aug 11 1994 Tracie Sucharski, Added Apple menus and memory
- * handling
- *
- **************************************************************************/
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- #include "pds.h"
-
- #define MM_TYPE 0x4D4D
- #define II_TYPE 0x4949
-
- #define version "24-Aug-94" /* version date of program */
-
- struct {
- char prgnam[9]; /* Program name */
- char hlpfil[13]; /* Help file name */
- char infile[128]; /* Input file name */
- char outfile[128]; /* Output file name */
- char img; /* Output image or browse image */
- char format; /* Output file format */
- } clemargs;
-
- long int resnumq = 420;
- long int resnum = 400;
-
-
- main()
- {
- char errbuf[132];
- long lines; /* Number of lines and sample of image */
- long samps;
- int i;
- FILE *fpi, *fpo; /* Input and output file pointers */
- int ret; /* Return code */
- char b[2];
- short int *j;
- char bitord;
-
- CursHandle hcur;
-
- PDSINFO *p;
-
- int labmod(char *text, char img, char bitord);
- int writetif(FILE *fp, long nl, long ns, CHARH *buf, char bitord);
-
- void macinit();
- void errmsg();
- void clemdcmp_menu();
-
-
- /*************************************************************************
- * Initialize the toolbox
- *************************************************************************/
- macinit();
-
- /*************************************************************************
- * Initialize input variables
- *************************************************************************/
- strcpy(clemargs.prgnam,"Clemdcmp");
- strcpy(clemargs.hlpfil,"clemdcmp.hlp");
- strcpy(clemargs.outfile," ");
- clemargs.img = 'i';
- clemargs.format = 'n';
-
- /*************************************************************************
- * Get input parameters
- *************************************************************************/
- clemdcmp_menu("NEW");
-
- /************************************************************************
- * Determine the bit order
- ************************************************************************/
-
- j = (short int *) b;
- b[0] = 1;
- b[1] = 0;
- if (*j == 1) bitord = 'l';
- else bitord = 'm';
-
- /***************************************************************************
- * The following call will open the compressed Clementine image and create
- * a structure containing the file objects.
- ****************************************************************************/
- hcur = GetCursor(4);
- if (hcur) SetCursor(*hcur);
- p = PDSR(clemargs.infile, &lines, &samps);
- if (p==NULL) {
- errmsg("ERROR:CLEMDCMP-Error in decompression toolkit",&resnumq);
- clemdcmp_menu("OLD");
- exit;
- }
-
- /****************************************************************************
- * If user chooses to output the full image, make sure it exists.
- ****************************************************************************/
- if (clemargs.img == 'i' && !(p->image)) {
- errmsg("ERROR:CLEMDCMP-This file does not contain a full image", &resnumq);
- clemdcmp_menu("OLD");
- exit;
- }
- /****************************************************************************
- * If user chooses to output the browse image, make sure it exists.
- ****************************************************************************/
- if (clemargs.img == 'b' && !(p->brw_imag)) {
- errmsg("ERROR:CLEMDCMP-This file does not contain a browse image",&resnumq);
- clemdcmp_menu("OLD");
- exit;
- }
-
- /******************************************************************************
- * Open output file
- ******************************************************************************/
- fpo = fopen(clemargs.outfile, "wb");
-
- /*****************************************************************************
- * For the pds formatted option, the labels will need to be modified before
- * writing out. The uncompressed output file will either be the image or
- * the browse image, so the pointer to the browse image will be deleted,
- * and the image pointer will be modified to point to the start of the data.
- * The pointer to the histogram will also need to be modified. The
- * ENCODING_COMPRESSION_RATIO will no longer be applicable, so the value is
- * changed to "N/A".
- ******************************************************************************/
- if (clemargs.format == 'p') {
- if (labmod(p->text, clemargs.img, bitord) < 0) {
- errmsg("ERROR:CLEMDCMP-Error reformatting labels",&resnumq);
- clemdcmp_menu("OLD");
- exit;
- }
- fwrite(p->text, strlen(p->text), 1, fpo);
- }
-
- if (clemargs.format == 'p' || clemargs.format == 'n') {
- /*****************************************************************************
- * If writing a pds formatted file, write the histogram data followed by
- * the image data, either the browse image or the full image. If writing
- * an unlabeled raw image write out only the image data.
- *****************************************************************************/
- if (p->hist == NULL && clemargs.format == 'p') {
- errmsg("ERROR:CLEMDCMP-Histogram is empty",&resnumq);
- clemdcmp_menu("OLD");
- exit;
- }
- if (clemargs.format == 'p') fwrite(p->hist, sizeof(long), 256, fpo);
- if (clemargs.img == 'i') {
- HLock(p->image);
- fwrite((CHARH *)*(p->image), lines*samps, 1, fpo);
- HUnlock(p->image);
- if (clemargs.format == 'n') {
- InitCursor();
- sprintf(errbuf, "The size of the raw image created is %ld lines by %ld samples \
- with no header or label data.",lines, samps);
- errmsg(errbuf, &resnum);
- }
-
- }
-
- if (clemargs.img == 'b') {
- HLock(p->brw_imag);
- fwrite((unsigned char *)*(p->brw_imag), p->browse_nrows*p->browse_ncols, 1, fpo);
- HUnlock(p->brw_imag);
- if (clemargs.format == 'n') {
- InitCursor();
- sprintf(errbuf, "The size of the raw image created is %d lines by %d samples \
- with no header or label data.", p->browse_nrows, p->browse_ncols);
- errmsg(errbuf, &resnum);
- }
-
- }
- }
-
-
-
- if (clemargs.img == 'b') { /* Write browse image */
-
- if (clemargs.format == 't') {
- HLock(p->brw_imag);
- /* if (writetif(fpo, p->browse_nrows, p->browse_ncols, p->brw_imag, bitord) < 0) {*/
- if (writetif(fpo, p->browse_nrows, p->browse_ncols, (unsigned char *)*(p->brw_imag), bitord) < 0) {
- errmsg("ERROR:CLEMDCMP-Error writing tiff format",&resnumq);
- clemdcmp_menu("OLD");
- exit;
- }
- HUnlock(p->brw_imag);
- }
-
- if (clemargs.format == 'g') {
- if (writegif(fpo, (long)p->browse_nrows, (long)p->browse_ncols, p->brw_imag) < 0) {
- errmsg("ERROR:CLEMDCMP-Error writing gif format",&resnumq);
- clemdcmp_menu("OLD");
- exit;
- }
- }
-
- }
-
- else { /* Write image */
-
- if (clemargs.format == 't') {
- HLock(p->image);
- if (writetif(fpo, lines, samps, (CHARH *)*(p->image), bitord) < 0) {
- errmsg("ERROR:CLEMDCMP-Error writing tiff format",&resnumq);
- clemdcmp_menu("OLD");
- exit;
- }
- HUnlock(p->image);
- }
-
- if (clemargs.format == 'g') {
- if (writegif(fpo, lines, samps, p->image) < 0) {
- errmsg("ERROR:CLEMDCMP-Error writing gif format",&resnumq);
- clemdcmp_menu("OLD");
- exit;
- }
- }
-
- }
-
-
- fclose(fpo);
-
- InitCursor();
- clemdcmp_menu("OLD");
-
- }
-
-
-
-
-
- int labmod(char *text, char img, char bitord)
- /*****************************************************************************
- *
- *_TITLE LABMOD - modify the clementine label to reflect the decompression
- *
- *_ARGS Type Variable I/O Description
- *_PARM char *text; I Pointer to clementine label
- *_PARM char img I Image Type (Full image or browse image)
- *_PARM char bitord I Bit order of current machine
- *_PARM int *ret O Return code
- * 0 - OK
- *
- *_DESC LABMOD will modify the clementine label to reflect the decompression,
- * and the possible rearranging of the browse image and image object.
- *
- *_HIST Apr 13 1994 Tracie Sucharski, USGS, Flagstaff Original Version
- * Jun 27 1994 Tracie Sucharski, Fixed bug when writing out the
- * browse image.
- * Jul 14 1994 Tracie Sucharski, Changed output value of ENCODING_
- * TYPE keyword.
- * Aug 23 1994 Tracie Sucharski, Added NOTE to image object if the
- * output image is the browse image, also correct
- * the DATA_TYPE keyword in the histogram object
- * to indicate the correct byte order.
- *
- ****************************************************************************/
- {
- int lbllen; /* Length of incoming label */
- int nlbllen; /* Length of outgoing label */
- char *start, *end; /* Index pointers */
- char sdummy[80];
- int nc; /* Number of characters */
- char byte[4]; /* Starting bytes of objects */
- int hbyte; /* Starting byte of Image Historgram */
- int ibyte; /* Starting byte of Image */
- int bbyte; /* Starting byte of Browse Image */
- int diff; /* Difference in bytes between input */
- /* label and output label */
- char labels[6000]; /* Temporary buffer to hold labels */
-
-
- lbllen = strlen(text);
-
- start = strstr(text, "^IMAGE_HISTOGRAM ");
- sscanf(start, "%s = %d", sdummy, &hbyte);
-
- start = strstr(text, "^IMAGE ");
- sscanf(start, "%s = %d", sdummy, &ibyte);
-
- start = strstr(text, "^BROWSE_IMAGE ");
- sscanf(start, "%s = %d", sdummy, &bbyte);
-
- /****************************************************************************
- * Get rid of pointer to browse image.
- ****************************************************************************/
- end = strchr(start,'\n');
- strcpy(start, end+1);
-
- /***************************************************************************
- * If browse image is being written, get rid of IMAGE object, rename
- * BROWSE_IMAGE object to IMAGE and add a note to indicate the output
- * image is the browse image.
- ***************************************************************************/
- if (img == 'b') {
- start = strstr(text, "OBJECT = IMAGE\n");
- end = strstr(start, "END_OBJECT");
- strcpy(start, end+11);
-
- start = strstr(text, " BROWSE_IMAGE");
- end = strchr(start, '\n');
- strncpy(labels, text, (start-text)+1);
- *(labels+(start-text+1)) = '\0';
- strcat(labels, "IMAGE");
- strcat(labels, end);
- strcpy(text, labels);
-
- end = strstr(start, "END_OBJECT");
- strncpy(labels, text, (end-text)+1);
- *(labels+(end-text)) = '\0';
- strcat(labels, " NOTE = \"Averaged subsampled EDR image\"\n");
- strcat(labels, end);
- strcpy(text, labels);
-
- }
-
- /***************************************************************************
- * If writing IMAGE object change ENCODING_COMPRESSION_RATIO and
- * ENCODING_TYPE keyvalues to "N/A", since the output file is uncompressed.
- ***************************************************************************/
- if (img == 'i') {
-
- start = strstr(text, "ENCODING_TYPE ");
- end = strchr(start, '\n');
- strncpy(labels, text, (end-text)-1);
- *(labels+(end-text-1)) = '\0';
- strcat(labels, " DECOMPRESSED\"");
- strcat(labels, end);
- strcpy(text, labels);
-
- start = strstr(text, "ENCODING_COMPRESSION_RATIO ");
- end = strchr(start, '\n');
- strncpy(labels, text, (start-text)+29);
- *(labels+(start-text+29)) = '\0';
- strcat(labels, "\"N/A\"");
- strcat(labels, end);
- strcpy(text, labels);
-
- /***************************************************************************
- * Get rid of the BROWSE_IMAGE object.
- ***************************************************************************/
- start = strstr(text, "OBJECT = BROWSE_IMAGE");
- end = strstr(start, "END_OBJECT");
- strcpy(start, end+11);
- }
-
- /****************************************************************************
- * If the bitorder is MSB which is different from that in the label(LSB),
- * change the label.
- ****************************************************************************/
- if (bitord == 'm') {
- start = strstr(text, "LSB_INTEGER");
- *start = 'M';
- }
-
- /****************************************************************************
- * Adjust the object pointers.
- ****************************************************************************/
- nlbllen = strlen(text);
- hbyte = nlbllen + 1;
- ibyte = hbyte + 1024;
-
- /*****************************************************************************
- * Now that there are new pointer values, write them out to the labels.
- *****************************************************************************/
- sprintf(byte, "%d", hbyte);
- nc = strlen(byte);
- start = strstr(text, "^IMAGE_HISTOGRAM ");
- strncpy(start+19, byte, nc);
-
- sprintf(byte, "%d", ibyte);
- nc = strlen(byte);
- start = strstr(text, "^IMAGE ");
- strncpy(start+19, byte, nc);
-
- return(0);
-
- }
-
-
-
- /*************************************************************************
- * ------------
- * | WRITETIF |
- * ------------
- *
- *_TITLE WRITETIF Writes decompressed Clementine data into TIF format
- *
- *_DESC WRITETIF takes decompressed Clementine data and writes an
- * uncompressed TIF formatted image.
- *
- *_HIST May 04 1994 Tracie Sucharski, USGS, Flagstaff Original Version
- *
- *************************************************************************/
- #define BLKSIZE 32768L
-
- int writetif(FILE *fp, long nl, long ns, CHARH *buf, char bitord)
- {
- unsigned int j, nblocks, rem; /* Added by Luis Perez 06/29/94 */
-
- int fputword(FILE *fp, short int n);
- int fputlong(FILE *fp, long n);
-
-
- /********************************************************************
- * Write out the TIF header
- ********************************************************************/
- if (bitord == 'm') fputword(fp, MM_TYPE);
- if (bitord == 'l') fputword(fp, II_TYPE);
- fputword(fp,42);
- fputlong(fp,8L);
-
- /********************************************************************
- * Construct the Image File Directory (IFD)
- ********************************************************************/
- fputword(fp, 8); /* Eight Tags */
-
- fputword(fp, 254); /* NewSubfileType */
- fputword(fp, 4); /* Long */
- fputlong(fp, 1L);
- fputlong(fp, 0L);
-
- fputword(fp, 256); /* ImageWidth */
- fputword(fp, 3); /* Short */
- fputlong(fp, 1L);
- if (bitord == 'm')
- fputlong(fp, ns*65536); /* Shift value into the two high order bytes */
- if (bitord == 'l')
- fputlong(fp, ns);
-
- fputword(fp, 257); /* ImageLength */
- fputword(fp, 3); /* Short */
- fputlong(fp, 1L);
- if (bitord == 'm')
- fputlong(fp, nl*65536); /* Shift value into the two high order bytes */
- if (bitord == 'l')
- fputlong(fp, nl);
-
- fputword(fp, 258); /* BitsPerSample */
- fputword(fp, 3); /* Short */
- fputlong(fp, 1L);
- if (bitord == 'm')
- fputlong(fp, 524288L); /* 8 Shifted into the two high order bytes */
- if (bitord == 'l')
- fputlong(fp, 8L);
-
- fputword(fp, 259); /* Compression */
- fputword(fp, 3); /* Short */
- fputlong(fp, 1L);
- if (bitord == 'm')
- fputlong(fp, 65536L); /* No compression */
- if (bitord == 'l')
- fputlong(fp, 1L);
-
- fputword(fp, 262); /* PhotometricInterpretation */
- fputword(fp, 3); /* Short */
- fputlong(fp, 1L);
- if (bitord == 'm')
- fputlong(fp, 65536L); /* 1 Shifted into the two high order bytes */
- if (bitord == 'l')
- fputlong(fp, 1L);
-
- fputword(fp, 273); /* StripOffsets - Start of image data */
- fputword(fp, 4); /* Long */
- fputlong(fp, 1L);
- fputlong(fp, 110L);
-
- fputword(fp, 277); /* SamplesPerPixel */
- fputword(fp, 3); /* Short */
- fputlong(fp, 1L);
- if (bitord == 'm')
- fputlong(fp, 65536L);
- if (bitord == 'l')
- fputlong(fp, 1L);
-
- fputlong(fp, 0L);
-
- /***********************************************************************
- * Write image data
- ***********************************************************************/
- /*!!!!!! BE CAREFUL HERE !!!!!!*/
- /* The third argument in fwrite is of type size_t, which under Turbo C
- becomes an unsigned short int (16 bit integer). This means you have
- to write the image data out in blocks of 64K bytes or less (32K is a
- good number).
- Added by Luis Perez 06/29/94. */
- #ifdef __TURBOC__
- nblocks = (nl*ns) / BLKSIZE;
- rem = (nl*ns) % BLKSIZE;
- for (j=0; j<nblocks; j++, buf+=BLKSIZE)
- fwrite(buf,1,BLKSIZE,fp);
- if ( rem > 0 )
- fwrite(buf,1,rem,fp);
- #else
- fwrite(buf, 1, nl*ns, fp);
- #endif
-
- return(0);
-
- }
-
-
-
-
- int fputword(FILE *fp, short int n)
- {
- fwrite(&n, 2, 1,fp);
-
- }
-
- int fputlong(FILE *fp, long n)
- {
- fwrite(&n, 4, 1, fp);
-
- }
-
-